<?php

/**
 * JingYao-backend
 *
 * @link     https://gitee.com/wang-zhihui-release/jingyao-backend
 * @apiDocument https://gitee.com/wang-zhihui-release/jingyao-backend/wikis/
 */

namespace App\Services;

use App\Enums\AssessTemplateTypeEnum;
use App\Enums\EnableStatusEnum;
use App\Enums\UserIdentityEnum;
use App\Exceptions\ApiException;
use App\Format\UserAssessLogFormat;
use App\Models\AssessTemplate;
use App\Models\AssessTemplateRule;
use App\Models\UserAssessLog;
use App\Models\UserProfile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class AssessUserService
{
    public function assess(UserAssessLogFormat $userAssessLogFormat)
    {
        $userProfileId = $userAssessLogFormat->getUserProfileId();
        /** @var null|UserProfile $userProfile */
        $userProfile = UserProfile::query()->select('identity')->where('id', $userProfileId)->first();
        if (empty($userProfile)) {
            Log::error('User profile Not Exist', [
                'data' => $userAssessLogFormat->toArray(),
            ]);
            throw new ApiException('要考核的用户不存在', 1);
        }
        if ($userProfile->identity == UserIdentityEnum::FLOW_USER) {
            return $this->assessFlowUser($userAssessLogFormat);
        }
        return $this->assessNotFlowUser($userAssessLogFormat);
    }

    public function assessTemp(int $type)
    {
        // 当前用户类型可用的模版只有一个
        /** @var null|AssessTemplate $assessTemp */
        $assessTemp = AssessTemplate::query()->where('type', $type)->where('status', EnableStatusEnum::ENABLE)->first();
        if (empty($assessTemp)) {
            throw new ApiException('不存在可用的审核模版', 1);
        }
        $assessTempRules = AssessTemplateRule::query()->where('assess_template_id', $assessTemp->id)->get();
        return $assessTempRules->toArray();
    }

    public function getUserAssess(int $userId, int $tempId)
    {
        /** @var UserProfile $userProfile */
        $userProfile = UserProfile::query()->select('id')->where('user_id', $userId)->first();
        $userProfileId = $userProfile->id;
        $logs = UserAssessLog::query()->where('user_profile_id', $userProfileId)
            ->where('assess_template_id', $tempId)
            ->get();

        $ruleIds = $logs->pluck('assess_template_rule_id')->toArray();
        $rules = AssessTemplateRule::query()->whereIn('id', $ruleIds)->get()->toArray();
        $ruleMap = array_column($rules, null, 'id');
        $logs = $logs->toArray();
        foreach ($logs as &$log) {
            $ruleId = $log['assess_template_rule_id'];
            $log['item'] = $ruleMap[$ruleId]['item'];
            $log['rule'] = $ruleMap[$ruleId]['rule'];
            $log['score_explain'] = $ruleMap[$ruleId]['score_explain'];
        }

        return $logs;
    }

    public function getUserAssessList(int $userId, int $page, int $pageSize, array $search)
    {
        /** @var null|UserProfile $userProfile */
        $userProfile = UserProfile::query()->select('user_id')->find($userId);
        if (empty($userProfile)) {
            throw new ApiException('用户信息不存在', 1);
        }
        $builder = UserAssessLog::query()->with('assessTemplate:type,title,name,id')
            ->where('user_profile_id', $userProfile->user_id)
            ->select('assess_template_id', DB::raw('max(assess_time) as push_time'), 'user_profile_id')
            ->groupBy('assess_template_id', 'user_profile_id');

        if (isset($search['start_date'], $search['end_date'])) {
            $builder->having('push_time', '>=', strtotime($search['start_date']));
            if (strlen($search['end_date']) > 10) {
                $builder->having('push_time', '<=', strtotime($search['end_date']));
            } else {
                $builder->having('push_time', '<=', strtotime($search['end_date']) + (24 * 3600));
            }
        }
        if (isset($search['start_date']) && ! isset($search['end_date'])) {
            $builder->having('push_time', '>=', strtotime($search['start_date']));
        }
        if (! isset($search['start_date']) && isset($search['end_date'])) {
            if (strlen($search['end_date']) > 10) {
                $builder->having('push_time', '<=', strtotime($search['end_date']));
            } else {
                $builder->having('push_time', '<=', strtotime($search['end_date']) + (24 * 3600));
            }
        }

        $count = $builder->get()->count();
        if (isset($search['order_type'])) {
            $builder->orderBy('push_time', $search['order_type']);
        }

        $list = $builder->skip(($page - 1) * $pageSize)->take($pageSize)->get()->toArray();
        foreach ($list as &$value) {
            $value['push_time'] = date('Y-m-d H:i:s', $value['push_time']);
        }

        return [
            'page' => $page,
            'page_size' => $pageSize,
            'count' => $count,
            'list' => $list,
        ];
    }

    private function assessFlowUser(UserAssessLogFormat $userAssessLogFormat)
    {
        $exist = AssessTemplate::query()->where('id', $userAssessLogFormat->getAssessTemplateId())
            ->where('type', AssessTemplateTypeEnum::ASESS_FLOW_USER)
            ->where('status', EnableStatusEnum::ENABLE)
            ->exists();
        if (! $exist) {
            throw new ApiException('模版不可用');
        }
        $userAssessLogFormat->setAssessTime(time());
        UserAssessLog::query()->create($userAssessLogFormat->toArrayNotNull());
        return true;
    }

    private function assessNotFlowUser(UserAssessLogFormat $userAssessLogFormat)
    {
        $exist = AssessTemplate::query()->where('id', $userAssessLogFormat->getAssessTemplateId())
            ->where('type', AssessTemplateTypeEnum::ASSESS_NOT_FLOW_USER)
            ->where('status', EnableStatusEnum::ENABLE)
            ->exists();
        if (! $exist) {
            throw new ApiException('模版不可用');
        }
        $userAssessLogFormat->setAssessTime(time());
        UserAssessLog::query()->create($userAssessLogFormat->toArrayNotNull());
        return true;
    }
}
